<?php
/*
 * @application shu_manage System
 * @author SkyWorld
 * @copyright SkyWorld
 * @version 1.0.0.0
 * @created on 2010-12-1
 */
 /*
 * @author SkyWorld
 * @Created on 2010-11-30
 */

/*
 * [ch]缓存类，用于实现页面的缓存功能
 * [ch]当第一访问某个PHP页面时，进行缓存操作，生成一个静态html文件
 * [ch]第二次访问页面时，检查缓存是否存在，如果缓存存在并且没有过期，则直接跳转到缓存文件
 * [ch]如果缓存存在但过期了，就要进行更新缓存操作
 */

class cache{
	/*
	 *[ch]私有属性，分别为缓存时间，缓存文件夹名，时区
	 */
	private $expireTime;
    private $cache_dir;
 	private $timezone;

 	/*
 	 * [ch]构造函数
 	 * [ch]需要参数，缓存时间，缓存文件夹名，时区
 	 */
	function __construct($expireTime=30,$cache_dir='cache',$timezone='Asia/Shanghai'){
	   $this->expireTime = $expireTime;
	   $this->timezone = $timezone;
	   if(!@is_dir($cache_dir)){
	  	if(!@mkdir($cache_dir,0777)){
	  		die ('Cache dir is not exist and can not be created');
	  	}
	   }else{
	  		$this->cache_dir = $cache_dir;
	   }

	   //[ch]设置时区，防止判断是否更新缓存时时间判断错误
	   date_default_timezone_set($this->timezone);
	 }

	 /*
	  * [ch]获取当前文件的url
	  */
	 private function getUrl(){


	  	if(!isset($_SERVER['REQUEST_URI'])){
	  		$url = $_SERVER['REQUEST_URI'];
	  	}else{
	  		$url = $_SERVER['SCRIPT_NAME'];
 	   		$url .= (!empty($_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : '';
	  	}
	  	return $url;
	 }

	 /*
	  * [ch]通过文件的url生成缓存文件的文件名
	  * [ch]因为在文件名中不能有/和?，所以要过滤掉这些内容
      * [ch]为了生成静态页面，把.php也过滤掉，并在末尾加上.html后缀
	  */
	 private function cacheFileName(){
	 	$cacheFileName = $this->getUrl();
	 	$pattern=array('/\//','/\?/','/\.php/');
		$replacement=array('','','');
		$cacheFileName.='.html';
		return preg_replace($pattern,$replacement,$cacheFileName);

	 }

	 /*
	  * [ch]判断缓存文件是否存在，如果存在且没有过期，则返回flase,否则返回ture
	  */
	  private function needRefreshCache($cacheFile){
			$cacheFile = $this->cache_dir."/".$cacheFile;
			if(file_exists($cacheFile) && filemtime($cacheFile) > (time()-$this->expireTime)){
			 	return false;
			}else{
			 	return true;
		    }
	  }

	  /*
	   * [ch]开始进行缓存操作函数
	   * [ch]该函数放在需要缓存内容之前
	   * [ch]如果缓存文件存在并且没有过期，则直接跳转至缓存文件并退出当前脚本
	   * [ch]如果缓存文件不存在，或已经过期，则当前脚本继续往下执行
	   */
	  public function startCaching(){
	  	ob_start();
	  	$cacheFileName = $this->cacheFileName();
	  	if(!$this->needRefreshCache($cacheFileName)){
	  		$url = $this->cache_dir."/".$cacheFileName;
	  		header("Location:$url");
	  		exit();
	  	}
	  }

	 /*
	  * [ch]结束缓存操作
	  * [ch]该函数放在需要缓存文件的末尾
	  * [ch]对需要缓存的内容进行缓存
	  */
 	 public function endCaching(){
 	   	$pageData = ob_get_contents();
 	   	$cacheFile = $this->cacheFileName();
 	   	$cacheFile = $this->cache_dir."/".$cacheFile;
 	   	 if(!$fp=fopen($cacheFile,'w')){
 	   	 	die ('Can not open cache file.');
 	   	 }
 	   	 if(!flock($fp,LOCK_EX)){//[ch]排它锁定
 	   	 	die('Can not lock cache file.');
 	   	 }
 	   	 if(!fwrite($fp,$pageData)){
 	   	 	die('Can not write cache file.');
 	   	 }
 	   	 flock($fp,LOCK_UN);//[ch]释放锁定
 	   	 ob_end_flush();
	  	 ob_end_clean();
 	   }

	   /*
	    * [ch]析构函数，用于释放资源
	    */
	  function __destruct(){}
 }
?>